//===============================================
// ScourgeProj.
//===============================================

class ScourgeProj extends Projectile;

var xEmitter Trail;
var() int BaseDamage;
var() float GloblingSpeed;
var() float RestTime;
var() float TouchDetonationDelay; // gives player a split second to jump to gain extra momentum from blast
var() float DripTime;
var() int MaxGoopLevel;

var int GoopLevel;
var float GoopVolume;
var Vector SurfaceNormal;
var int Rand3;
var bool bCheckedSurface;
var() bool bMergeGlobs;
var bool bDrip;
var bool bOnMover;

var() Sound ExplodeSound;
var AvoidMarker Fear;

function ProcessTouch(Actor Other, vector HitLocation)
{
   if (Pawn(Other) != none && EnyaraPlayerController(Pawn(Other).Controller) != none) {
     EnyaraPlayerController(pawn(Other).Controller).drainMana(20);
   }
}

replication
{
 reliable if (bNetInitial && Role == ROLE_Authority)
  Rand3;
}

simulated function PostBeginPlay()
{
 Super.PostBeginPlay();

 SetOwner(None);

 LoopAnim('flying', 1.0);

 if (Role == ROLE_Authority)
 {
  Velocity = Vector(Rotation) * Speed;
  Velocity.Z += TossZ;
 }

 if (Role == ROLE_Authority)
   Rand3 = Rand(3);
 if ( (Level.NetMode != NM_DedicatedServer) && ((Level.DetailMode == DM_Low) || Level.bDropDetail) )
 {
  bDynamicLight = false;
  LightType = LT_None;
 }
}

function AdjustSpeed()
{
 if ( GoopLevel < 1 )
  Velocity = Vector(Rotation) * Speed;
 else
  Velocity = Vector(Rotation) * Speed * (0.4 + GoopLevel)/(1.4*GoopLevel);
 Velocity.Z += TossZ;
}

simulated function PostNetBeginPlay()
{
 if (Role < ROLE_Authority && Physics == PHYS_None)
 {
  Landed(Vector(Rotation));
 }
}

simulated function Destroyed()
{
 if ( !bNoFX && EffectIsRelevant(Location,false) )
 {
  Spawn(class'xEffects.GoopSmoke');
  Spawn(class'xEffects.GoopSparks');
 }
 if ( Fear != None )
  Fear.Destroy();
 if (Trail != None)
  Trail.Destroy();
 Super.Destroyed();
}

auto state Flying
{
 simulated function Landed( Vector HitNormal )
 {
  local Rotator NewRot;
  local int CoreGoopLevel;

  if ( Level.NetMode != NM_DedicatedServer )
  {
   PlaySound(ImpactSound, SLOT_Misc);
   // explosion effects
  }

  SurfaceNormal = HitNormal;

  // spawn globlings
  CoreGoopLevel = Rand3 + MaxGoopLevel - 3;
  if (GoopLevel > CoreGoopLevel)
  {
//   if (Role == ROLE_Authority)
//    SplashGlobs(GoopLevel - CoreGoopLevel);
//   SetGoopLevel(CoreGoopLevel);
  }
  spawn(class'BioDecal',,,, rotator(-HitNormal));

  bCollideWorld = false;
  SetCollisionSize(GoopVolume*10.0, GoopVolume*10.0);
  bProjTarget = true;

  NewRot = Rotator(HitNormal);
  NewRot.Roll += 32768;
  SetRotation(NewRot);
  SetPhysics(PHYS_None);
  bCheckedsurface = false;
  if ( (Level.Game != None) && (Level.Game.NumBots > 0) )
   Fear = Spawn(class'AvoidMarker');
  GotoState('OnGround');
 }

 simulated function HitWall( Vector HitNormal, Actor Wall )
 {
  Landed(HitNormal);
  if ( !Wall.bStatic && !Wall.bWorldGeometry )
  {
   bOnMover = true;
   SetBase(Wall);
   if (Base == None)
    BlowUp(Location);
  }
 }

 simulated function ProcessTouch(Actor Other, Vector HitLocation)
 {
  local BioGlob Glob;

  Glob = BioGlob(Other);

        if (EnyaraPlayerController(Pawn(Other).Controller) != none) {
           EnyaraPlayerController(pawn(Other).Controller).drainMana(20);
        }

  if ( Glob != None )
  {
   if (Glob.Owner == None || (Glob.Owner != Owner && Glob.Owner != self))
   {
    if (bMergeGlobs)
    {
     Glob.MergeWithGlob(GoopLevel); // balancing on the brink of infinite recursion
     bNoFX = true;
     Destroy();
    }
    else
    {
     BlowUp( HitLocation );
    }
   }
  }
  else if (Other != Instigator && (Other.IsA('Pawn') || Other.IsA('DestroyableObjective') || Other.bProjTarget))
   BlowUp( HitLocation );
  else if ( Other != Instigator && Other.bBlockActors )
   HitWall( Normal(HitLocation-Location), Other );
 }
}

state OnGround
{
 simulated function BeginState()
 {
  PlayAnim('hit');
  SetTimer(RestTime, false);
 }

 simulated function Timer()
 {
  if (bDrip)
  {
   bDrip = false;
   SetCollisionSize(default.CollisionHeight, default.CollisionRadius);
   Velocity = PhysicsVolume.Gravity * 0.2;
   SetPhysics(PHYS_Falling);
   bCollideWorld = true;
   bCheckedsurface = false;
   bProjTarget = false;
   LoopAnim('flying', 1.0);
   GotoState('Flying');
  }
  else
  {
   BlowUp(Location);
  }
 }

 simulated function ProcessTouch(Actor Other, Vector HitLocation)
 {
  if ( Other.IsA('Pawn') && (Other != Base) )
  {
   bDrip = false;
   SetTimer(TouchDetonationDelay, false);
  }
 }

 function TakeDamage( int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Momentum, class<DamageType> DamageType )
 {
  if (DamageType.default.bDetonatesGoop)
  {
   bDrip = false;
   SetTimer(0.1, false);
  }
 }

 simulated function AnimEnd(int Channel)
 {
  local float DotProduct;

  if (!bCheckedSurface)
  {
   DotProduct = SurfaceNormal dot Vect(0,0,-1);
   if (DotProduct > 0.7)
   {
    PlayAnim('Drip', 0.66);
    bDrip = true;
    SetTimer(DripTime, false);
    if (bOnMover)
     BlowUp(Location);
   }
   else if (DotProduct > -0.5)
   {
    PlayAnim('Slide', 1.0);
    if (bOnMover)
     BlowUp(Location);
   }
   bCheckedSurface = true;
  }
 }

 simulated function MergeWithGlob(int AdditionalGoopLevel)
 {
  local int NewGoopLevel, ExtraSplash;
  NewGoopLevel = AdditionalGoopLevel + GoopLevel;
  if (NewGoopLevel > MaxGoopLevel)
  {
   Rand3 = (Rand3 + 1) % 3;
   ExtraSplash = Rand3;
  // if (Role == ROLE_Authority)
  //  SplashGlobs(NewGoopLevel - MaxGoopLevel + ExtraSplash);
   NewGoopLevel = MaxGoopLevel - ExtraSplash;
  }
 // SetGoopLevel(NewGoopLevel);
  SetCollisionSize(GoopVolume*10.0, GoopVolume*10.0);
  PlaySound(ImpactSound, SLOT_Misc);
  PlayAnim('hit');
  bCheckedSurface = false;
  SetTimer(RestTime, false);
 }

}

function BlowUp(Vector HitLocation)
{
 if (Role == ROLE_Authority)
 {
  Damage = BaseDamage + Damage * GoopLevel;
  DamageRadius = DamageRadius * GoopVolume;
  MomentumTransfer = MomentumTransfer * GoopVolume;
  if (Physics == PHYS_Flying) MomentumTransfer *= 0.5;
  DelayedHurtRadius(Damage, DamageRadius, MyDamageType, MomentumTransfer, HitLocation);
 }

 PlaySound(ExplodeSound, SLOT_Misc);

 Destroy();
 //GotoState('shriveling');
}

defaultproperties
{
  Speed=10000.000000
  TossZ=0.000000
  bSwitchToZeroCollision=True
     BaseDamage=0
  DamageRadius=120.000000
  MomentumTransfer=40000.000000
  MyDamageType=Class'Enyara.DamScourge'
  ImpactSound=SoundGroup'WeaponSounds.BioRifle.BioRifleGoo2'
  MaxEffectDistance=700.000000
  LightType=LT_Steady
  LightEffect=LE_QuadraticNonIncidence
  LightHue=15
  LightSaturation=10
  LightBrightness=190.000000
  LightRadius=0.600000
  bDynamicLight=True
  bNetTemporary=False
  bOnlyDirtyReplication=True
  Physics=PHYS_Falling
  LifeSpan=10.000000
  Mesh=VertMesh'XWeapons_rc.GoopMesh'
  DrawScale=1.200000
  Skins(0)=FinalBlend'XEffectMat.goop.GoopFB'
  AmbientGlow=80
  SoundVolume=255
  SoundRadius=100.000000
  CollisionRadius=2.000000
  CollisionHeight=2.000000
  bUseCollisionStaticMesh=True
}
